#coding=utf8
from config import Config
import datetime
import requests
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from dominate.tags import *
from pymongo import MongoClient
import dominate
from email.mime.base import MIMEBase
from email.header import Header
from email import encoders
import smtplib
import pymysql
import re
import os
import time
from dominate.util import raw
import getpass
from subprocess import Popen, PIPE
import sys

test_mail=Config.test_mail
report_server=Config.report_server
sonar_server=Config.sonar_server
host=Config.host
user=Config.user
password=Config.password
db=Config.db
port=Config.port
server_ip=Config.server_ip

try:
    days=sys.argv[1]
except :
    days=7
with open('style_file_no_tabs','r',encoding='utf8') as f:
    style_content=f.readlines()


no_api_list=['Service', 'Portal', "Report","Logmon","oneSearch","Dashboard"]
no_api_list=[i.upper() for i in no_api_list]

class Prod_datas():
    def __init__(self,job_name=None,datas=None,init=False):
        if datas is None or datas.get(job_name,None) in (None,{}) and init:
            datas.update({job_name:{}})
        self.datas = datas
        self.key = job_name

    def set_data(self,data=None,key=None):
        if self.key and key:
            self.datas[key].update(data)

    def get_datas(self,type=None,default=None,key=None):
        if key and self.key:
            if type:
                return self.datas[key].get(type,default)
            return self.datas[key]
        else:
            return self.datas

    def index(self,search,single=True):
        length=len(search)
        keys=[]
        for key,values in self.datas.items():
            all = 0
            for k,v in search.items():
                if values.get(k,None)==v:
                    all+=1
                if all==length:
                    keys.append(key)
        if len(keys)==0:
            return None
        if not single:
            return keys
        else:
            return keys[0]


    def has_key(self,key=None):
        if key in self.datas.keys():
            return True
        else:
            return False


def run_cmd(cmd, run_as=None):
    close_fds = os.name != 'nt'
    p = Popen(
        cmd,
        stdout=PIPE,
        stdin=PIPE,
        stderr=PIPE,
        shell=True,
        close_fds=close_fds)
    stdout, stderr = p.communicate()
    if p.returncode and stderr:
        print('Run cmd: {} \nCode: {}, Stderr: {}'.format(cmd, p.returncode, stderr))
    return p.returncode, stdout.strip()


def get_openapi_result(report_path):
    try:
        has_str=False
        with open(report_path, 'r') as f:
            f.seek(0)
            lines = f.readlines()
            # print(lines)
            for i in lines:
                if "测试用例" in i:
                    has_str=True
                    res=i

        if not has_str:
            #兼容jmeter测试结果
            with open(report_path, 'r') as f:
                res = f.readlines()
            res = ','.join(res)
            res = re.findall(r"<table (.*?)</table>", res, re.S)[0]
            # print('res',res)
            res=res.split('</td><td align="center">')
            # print('res', res)
            # result='执行总数：{},成功数：{}，失败数：{},成功率：{}。'.format(res[0].split('>')[-1],res[1],res[2],res[3])
            fail_num=int(res[2].strip())
            success_num=int(res[1].strip())
        else:
            report = re.findall(r"<div>(.*?)<span(.*?)>(.*?)</span>(.*?)</div>", res, re.S)
            print(report)
            success_num = int(report[0][2].strip())
            result = (report[0][0] + report[0][2] + report[0][3])
            fail_num = re.findall(r"通过，(.*?)个未通过", result, re.U)
            if fail_num in (0, ' 0 ', [],'0'):
                return success_num,0
            else:
                return success_num,fail_num[0].strip()
        return success_num,fail_num
    except Exception as e:
        print(e)
        return None,None


def dictfetchall(cursor):
    columns = [col[0] for col in cursor.description]
    return [
        dict(zip(columns, row))
        for row in cursor.fetchall()
        ]


def get_mysql_data(sql_cmd):
    global host,user,password,db,port
    # print(sql_cmd)
    connection = pymysql.connect(host=host, user=user, password=password, db=db, port=port, charset='UTF8')

    cursor = connection.cursor()
    cursor.execute(sql_cmd.encode('utf8'))
    datas = dictfetchall(cursor)
    # print(datas)
    connection.commit()
    connection.close()
    return datas


def find_newest_file(path_file, file_name=None, end=None):
    lists = os.listdir(path_file)
    if file_name is not None:
        lists_temp = []
        for i in lists:
            name = i.split(os.sep)[-1]
            if name.startswith(file_name) and name.endswith(end):
                lists_temp.append(i)
        lists = lists_temp
    if  len(lists)>=1:
        lists.sort(key=lambda fn: os.path.getmtime(path_file + os.sep + fn))
        file_newest = os.path.join(path_file, lists[-1])
        return file_newest
    else:
        return None


def get_sonar_file(filename):
    '''获取代码扫描信息'''
    global sonar_server
    line = None
    bugs = None
    rate = None
    if not os.path.exists('/usr/share/nginx/html/sonar_reports'):
        return None,None,None
    sonar_report_result = find_newest_file('/usr/share/nginx/html/sonar_reports', file_name=filename,end='.result')
    if not sonar_report_result:
        sonar_report_result = find_newest_file('/usr/share/nginx/html/sonar_reports', file_name=filename.upper(), end='.result')
    if not sonar_report_result:
        sonar_report_result = find_newest_file('/usr/share/nginx/html/sonar_reports', file_name=filename.lower(), end='.result')
    if sonar_report_result:
        print('sonar_report_result',sonar_report_result)
        with open(sonar_report_result, 'r') as f:
           res_line = f.readline()
        # res = re.search("扫描代码行数:(.*?),需解决bug数:(.*?), 漏洞(.*?)代码覆盖率:(.*?),重复率", res_line)
        # print(res)
        res = re.search("扫描代码行数:(.*?)[，,][ ]*需解决bug数:(.*?), 漏洞(.*?)代码覆盖率:(.*?),重复率", res_line)
        print(res)
        # sys.exit(1)
        if res:
            line=res.group(1)
            bugs = res.group(2)
            rate = res.group(4)
        print('1')
    else:
        url='http://{}/?projectname={}'.format(sonar_server,filename.split('.html')[0])
        sonars = requests.get(url)
        res = sonars.content
        res = re.search("bug:(.*?),(.*?)覆盖率:(.*?),", res)
        if res:
            line=res.group(1)
            bugs = res.group(1)
            rate = res.group(3)
        print('2')

    try:
        cmd = "select sonar_bugs,sonar_test_rate from jenkins_job where " \
                              "sonar_test_rate not in (0,'NaN') and prod_name='{}' order by TIMESTAMP desc".format(filename.upper())
        sonar_sql_result = get_mysql_data(cmd)
        if len(sonar_sql_result) >= 1 and rate in (None, 'NaN', '') or not isinstance(rate, (float, int)) or int(rate) == 0:
                rate = sonar_sql_result[0]['sonar_test_rate']
    except Exception as e:
        print('sonar_test_rate error:',e)
        pass

    # try:
    #     cmd = "select sonar_bugs,sonar_test_rate from jenkins_job where " \
    #           "line not in (0,'NaN') and prod_name='{}' order by TIMESTAMP desc".format(filename.upper())
    #     sonar_sql_result = get_mysql_data(cmd)
    #     if len(sonar_sql_result) >= 1 and ( rate in (None, 'NaN', '') or not isinstance(rate, (float, int)) or int(
    #             rate) == 0):
    #         rate = sonar_sql_result[0]['sonar_test_rate']
    # except Exception as e:
    #     print('sonar_test_rate error:', e)
    #     pass
        #
            # if sonar_sql_result[0].get('line',None) and \
            #         (line in (None, 'NaN', '') or not isinstance(rate, (float, int)) or int(rate) == 0):
            #     line = sonar_sql_result[0].get('line',None)
            #     bugs = sonar_sql_result[0].get('sonar_bugs',None)

    print('line,bugs,rate', line, bugs, rate)
    return line, bugs, rate


def make_html(daytime):
    '''获取主要数据'''
    global no_api_list,report_server
    #获取jenkins流水线信息
    cmd="select t.prod_name,t.job_name ,t.job_desc,t.success,t.all_result,t.col_id from " \
        "(select prod_name,job_name ,job_desc,sum(status) success,count(*) all_result,max(col_id) col_id  from jenkins.jenkins_job " \
        " where timestamp>='{}' group by prod_name,job_name,job_desc ) t order by t.prod_name  desc".format(daytime)#t.success/t.all_result
    jenkins_datas=get_mysql_data(cmd)
    all_datas={}
    for i in jenkins_datas:
        data=Prod_datas(job_name=i['job_name'],datas=all_datas,init=True)
        data.set_data(key=i['job_name'] ,data={'job_desc': i['job_desc'],
                                               'job_name': i['job_name'],
                                               'whole_success':i['success'],
                                               'whole_run':i['all_result']})
        all_datas=data.get_datas()


    #获取单元测试和代码扫描的用例执行信息
    cmd = "select s.prod_name,s.job_name,s.success,s.fail_num,s.sonar_bugs,s.sonar_test_rate,s.sonar_report,s.openapi_report from (SELECT t1.prod_name,t1.job_name,MAX(id) as id FROM " \
          "jenkins_job t1 where t1.success is not NULL GROUP BY t1.prod_name,t1.job_name ORDER BY id DESC) t,jenkins_job s  where t.id=s.id"
    yapi_datas=get_mysql_data(cmd)

    for i in yapi_datas:
        # print(all_datas)
        data=Prod_datas(i['job_name'],datas=all_datas)
        if not data.has_key(key=i['job_name']):
            continue
        data.set_data(key= i['job_name'],data={'prod_name':i['prod_name'],
                       'job_name': i['job_name'],
                       'success': int(i['success']),
                       'sonar_bugs': int(i['sonar_bugs']) if i['sonar_bugs'] is not None else 0,
                       'fail_num': int(i['fail_num']),
                         'sonar_test_rate':  i.get('sonar_test_rate','NaN'),
                         'sonar_report':  str(i.get('sonar_report', 'NaN')),
                         'openapi_report': str(i.get('openapi_report', 'NaN'))})

        all_datas = data.get_datas()


    # 获取jmeter基准测试信息
    cmd = "select s.product_name,s.version,ABS(s.success_count) success_count,ABS(s.count) count,s.jenkinsReportUrl from jmeter_report s INNER JOIN " \
          "(select product_name,max(build_time) as maxTime from jmeter_report group by product_name) b " \
          "on s.product_name=b.product_name and b.maxTime=s.build_time  where  s.product_name=b.product_name;"
    jmeter_datas=get_mysql_data(cmd)
    # print('jmeter_datas',jmeter_datas)
    jmeter_results = {}
    for i in jmeter_datas:
        # print(i)
        product_name = i['product_name'].upper()
        data = Prod_datas(datas=all_datas,job_name=None)
        # print(data.get_datas())
        job_name=data.index({'prod_name':product_name})
        # print(job_name)
        if not job_name:
            continue
        data = Prod_datas(job_name=job_name,datas=all_datas)
        data.set_data(key=job_name,data={'jmx_result':'{:.2f}%({}/{})'.format(100*float(i['success_count'])/float(i['count'] if i['count']!=0 else 1),i['success_count'],i['count'])})
        data.set_data(key=job_name,data={'jmx_report': 'http://{}/jmeter_report/{}'.format(report_server,i['jenkinsReportUrl']) if not i['jenkinsReportUrl'].startswith('http://') else 'None'})
        all_datas = data.get_datas()
    # print('all_datas', all_datas['Notify_WholeProcess'].keys())

    #获取yapi场景信息
    cmd="""select max(b.testsuit_id) testsuit_id,c.yapi_project_name prod_name,b.cases_total_num total,b.cases_success_num success,b.yapi_interface_col_name from
(SELECT a.yapi_interface_col_id,a.yapi_interface_col_name,a.cases_total_num,a.cases_success_num,a.testsuit_id FROM yapi_testsuit a
inner join
      (select yapi_interface_col_id,max(timestamp) as maxTime from yapi_testsuit GROUP BY yapi_interface_col_id) maxtime
on a.yapi_interface_col_id = maxtime.yapi_interface_col_id and maxtime.maxTime = a.timestamp) b,yapi_info c where
b.yapi_interface_col_id=c.yapi_interface_col_id and b.yapi_interface_col_name like '%场景%'
group by prod_name,total,success,yapi_interface_col_name order by yapi_interface_col_name """
    yapi_scene=get_mysql_data(cmd)
    # yapi_scene_result={}
    for i in yapi_scene:
        data = Prod_datas(datas=all_datas,job_name=None)
        job_name = data.index({'prod_name': i['prod_name'].upper()})
        if not job_name:
            continue
        data = Prod_datas(job_name,datas=all_datas)
        total=data.get_datas(type='scene_total',default=0,key=job_name)
        success = data.get_datas(type='scene_success', default=0,key=job_name)
        data.set_data(key=job_name,data={'scene_total': int(i.get('total',0))+total})
        data.set_data(key=job_name,data={'scene_success': int(i.get('success',0))+success})
        data.set_data(key=job_name,data={'scene_suit': i['testsuit_id']})
        all_datas=data.get_datas()

    for i in jenkins_datas:
        # 获取冒烟测试和代码扫描信息
        data = Prod_datas(datas=all_datas,job_name=None)
        job_names = data.index({'prod_name': i['prod_name'].upper()},single=False)
        if job_names:
            for job_name in job_names:
                data = Prod_datas(datas=all_datas,job_name=job_name)
                report_name = data.get_datas(type='openapi_report', key=job_name).strip().split('/')[-1]

                try:
                    bugs=None
                    line=None
                    # if rate in (None, 'NaN', '') :
                    line, bugs, rate=get_sonar_file(job_name.split('_')[0])
                    data.set_data(key=job_name, data={'sonar_bugs': bugs})
                    data.set_data(key=job_name, data={'sonar_line': line})
                    data.set_data(key=job_name, data={'sonar_test_rate': '{}'.format(rate)})
                except Exception as e:
                    print(e)
                    data.set_data(key=job_name, data={'sonar_bugs': bugs})
                    data.set_data(key=job_name, data={'sonar_line': line})
                    data.set_data(key=job_name, data={'sonar_test_rate': 'NaN'})
                    pass

                if job_name.split('_')[0].upper() in no_api_list:
                    data.set_data(key=job_name, data={'openapi_success': 0})
                    data.set_data(key=job_name, data={'openapi_fail': 0})
                    data.set_data(key=job_name, data={'openapi_all': 0})
                    all_datas = data.get_datas()
                    continue

                report_path = find_newest_file('/usr/share/nginx/html/yapi_report/',
                                               file_name=report_name.split('_')[0], end='.html')
                print('report_path',report_path)
                success_num=None
                try:
                    success_num, fail_num = get_openapi_result(report_path)
                    if i['prod_name'].lower() in ('monitor','alert','store-metric','databank','network'):
                        data.set_data(key=job_name, data={'scene_total':int(success_num) + int(fail_num)})
                        data.set_data(key=job_name, data={'scene_success': success_num})
                    data.set_data(key=job_name,data={'openapi_success': success_num})
                    data.set_data(key=job_name,data={'openapi_fail': fail_num})
                    data.set_data(key=job_name,data={'openapi_all': int(success_num) + int(fail_num)})
                except Exception as e:
                    print(e)
                    pass
                if success_num is None:
                    file_newest = find_newest_file('/usr/share/nginx/html/yapi_report/', file_name=report_name.split('_')[0],end='.html')
                    if file_newest:
                        success_num, fail_num = get_openapi_result(file_newest)
                        data.set_data(key=job_name, data={'openapi_success': success_num})
                        data.set_data(key=job_name, data={'openapi_fail': fail_num})
                        data.set_data(key=job_name, data={'openapi_all': int(success_num) + int(fail_num)})
                    else:
                        print('未找到报告文件:{}'.format(report_path))

                all_datas=data.get_datas()
    # print('all_datas',all_datas)
    return all_datas


def run_cmd(cmd, run_as=None):
    if run_as and os.name != 'nt' and run_as != getpass.getuser():
        cmd = '''su - {} -c '{}' '''.format(run_as, cmd)
        # print(cmd)
        close_fds = os.name != 'nt'
        p = Popen(
            cmd,
            stdout=PIPE,
            stdin=PIPE,
            stderr=PIPE,
            shell=True,
            close_fds=close_fds)
        stdout, stderr = p.communicate()
        if p.returncode and stderr:
            print('Run cmd: {} \nCode: {}, Stderr: {}'.format(cmd, p.returncode, stderr))
        return p.returncode, stdout.strip()


def get_zentao(days):
    global host, user, password, db, port
    # print(sql_cmd)
    connection = pymysql.connect(host=host, user=user, password=password, db=db, port=port, charset='UTF8')

    cursor = connection.cursor()

    #取此刻的时间戳
    now_time = int(time.time())
    day_time = int(time.mktime(time.strptime(time.strftime("%Y-%m-%d", time.localtime(now_time)), "%Y-%m-%d")))
    #取当天0点的时间
    now_time = int(time.mktime(datetime.date.today().timetuple()))
    #取几天前的数据
    now_time=datetime.date.today()
    day_time= now_time - datetime.timedelta(days = int(days))
    day_time=int(time.mktime(day_time.timetuple()))
    # print(day_time)
    #判断数据是否存在，若不存在返回空
    cmd = "SELECT count(*) nums FROM `zentao_info` WHERE timestamp>='{}'".format(day_time)
    cursor.execute(cmd.encode('utf8'))
    jenkins_datas = dictfetchall(cursor)
    # print(jenkins_datas)
    if jenkins_datas[0]['nums']==0:
        return None

    # cmd = "SELECT build_name,sum(bugs_total) bugs_total,sum(bugs_active) bugs_active,sum(bugs_resolved) bugs_resolved," \
    #       "sum(bugs_closed) bugs_closed,sum(bugs_reactive) bugs_reactive FROM `zentao_info` " \
    #       "WHERE timestamp>='{}' group by build_name order by bugs_total desc".format(day_time)
    cmd="""
select a.build_name,b.bugs_total,b.bugs_active,b.bugs_resolved,a.bugs_closed,a.bugs_reactive from
(select build_name,sum(bugs_closed) bugs_closed,sum(bugs_reactive) bugs_reactive FROM `zentao_info` group by build_name) a,
(SELECT build_name,sum(bugs_total) bugs_total,sum(bugs_active) bugs_active,sum(bugs_resolved) bugs_resolved FROM `zentao_info` WHERE timestamp>='1604851200' group by build_name) b
where a.build_name=b.build_name order by b.bugs_total desc
    """
    # print(cmd)
    cursor.execute(cmd.encode('utf8'))
    jenkins_datas = dictfetchall(cursor)
    # print(jenkins_datas)
    connection.close()
    return jenkins_datas


class MakeHTML(object):
    def __init__(self):
        main = html()
        self.main=main

    def add_head(self,style_content=None):
        header_tag = head()
        if style_content:
            header_tag.add(style(style_content))
            self.main.add(header_tag)

    def add_body(self):
        self.main.add(body())

    def add_div(self,parent,cls_content=None):
        div_content = div(cls=cls_content)
        parent.add(div_content)


def make_report(prod_name,ids):
    '''获取场景化测试的具体用例'''
    global style_content

    suit_data_results=[]
    real_results=[]
    for i in ids.split(','):
        if i in real_results:
            continue
        else:
            real_results.append(i)
    # print('prod_name', prod_name, real_results)
    for i in real_results:
        cmd = """select a.*,b.yapi_interface_col_name,b.yapi_interface_col_id from yapi_testsuit_steps a ,yapi_testsuit b
    where a.testsuit_id=b.testsuit_id and
     a.testsuit_id in ('{}') order by a.testsuit_step_num;""".format(i)
        suit_datas = get_mysql_data(cmd)
        # print('suit_datas',suit_datas)
        if not suit_datas:
            return
        else:
            suit_data_results.append(suit_datas)

    case_main = html()
    header=head()

    header.add(meta( http_equiv="Content-Type",content="text/html; charset=utf-8"))
    header.add(style(style_content))
    title_content="{} 场景用例执行情况".format(prod_name)
    # print('title_content',title_content)
    header.add(title(title_content))
    case_main.add(header)

    with case_main.add(body()) as case:
        content = div(cls="content")
        content.add(h1(title_content))
        body.add(content)


        with table(cls='details',border="1",cellspacing="0", padding="0") as table_content:
            case_l = tr()
            case_l += th('序号')
            case_l += th('场景名称')
            case_l += th('用例名称')
            case_l += th('接口路径')
            case_l += th("测试结果")
            j=0
            for suit_datas in suit_data_results:
                i = 0
                # print('suit_datas',suit_datas)
                for case_line in suit_datas:
                    case_l = tr()
                    if i==0:
                        j += 1
                        case_l += td(j)
                        case_l += td(case_line['yapi_interface_col_name'])
                        i+=1

                    else:
                        case_l+=td(" ")
                        case_l += td(" ")
                    case_l += td(case_line['case_name'])
                    case_l += td(case_line['case_path'])
                    if case_line['case_result']=='验证通过':
                        status="#32CD32"
                    else:
                        status="#FF0000"
                    case_l += td(case_line['case_result'],bgcolor=status, align="center")
    if os.path.exists('/usr/share/nginx/html/scene_report/'):
        file_path='/usr/share/nginx/html/scene_report/'+prod_name + '.html'
        with open(file_path, 'w',encoding='utf-8') as f:
            f.write(case_main.render())
    else:
        file_path=prod_name + '.html'
        with open(file_path, 'w',encoding='utf-8') as f:
            f.write(case_main.render())
    return prod_name + '.html'


def add_score(bugs,test_rate,openapi,scene):
    print('bugs, test_rate, openapi, scene',bugs, test_rate, openapi, scene)
    score = 0
    if bugs=='NaN':
        bugs=None
    if test_rate=='NaN':
        test_rate=None
    if openapi=='NaN':
        openapi=None
    if scene=='NaN':
        scene=None

    try:
        test_rate=float(test_rate)
    except:
        pass

    try:
        bugs=int(bugs)
    except:
        pass

    try:
        openapi = float(openapi)
    except:
        pass

    try:
        scene = float(scene)
    except:
        pass

    if isinstance(bugs, int):
        bugs=int(bugs)
        if bugs>10:
            score+=10
        elif bugs>0 and bugs<=10:
            score+=20
        elif bugs==0:
            score += 30

    if isinstance(test_rate, float):
        if test_rate<=30:
            score += 5
        elif test_rate>30 and test_rate<60:
            score += 15
        elif test_rate>=60:
            score += 30
    temp=0
    if isinstance(openapi, float):
        temp+=15*float(openapi)/100

    if isinstance(scene, float):
        temp+=15*float(scene)/100

    score+=temp
    if temp==30:
        score += 10
    return score


def txt2xml(datas2,days):
    '''主体页面'''
    try:
        if 'linux' in sys.platform:
            file_name = '/usr/share/nginx/html/reports/report_{}'.format(days)
        else:
            file_name = 'whole_process_statics'
    except Exception as e:
        print(e)
        sys.exit(1)
    try:
        reports={}
        global no_api_list
        def create_th_div(a,b):
            th_div = div()
            th_div.add(label(a))
            th_div.add(br())
            th_div.add(label(b))
            return th_div

        main = dominate.document(title="UYUN-开发流水线质量看板")
        with main.head:
            style(style_content)
            script(src="http://{}/js/jquery-latest.js".format(report_server))
            script(src="http://{}/js/jquery.tablesorter.min.js".format(report_server))
            meta(http_equiv="Content-Type", content="text/html; charset=UTF-8")


        # htmlfile=MakeHTML()
        tags={1:'流水线',2:'禅道'}
        tables=[]
        with main.add(body()):

            container=div(cls='container')
            body.add(container)
            # caption('summary:')
            section_name=section(cls='tabs')
            container.add(section_name)
            # for i in range(1,2):
                # section_name.add(input_(id="tab-{}".format(i), type="radio", name="radio-set", cls="tab-selector-{}".format(i), checked="checked"))
                # section_name.add(label(tags[i],for_="tab-{}".format(i),cls="tab-label-{}".format(i)))
            section_name.add(div(cls='clear-shadow'))
            content=div(cls="content")
            section_name.add(content)
            with table(cls='details',border="1",cellspacing="0", padding="0",id="pro_list") as table1:
                # l = tr(bgcolor="#d3d7cf", align="center")

                trs = tr()
                trs += th('作业描述')
                trs += th('流水线触发作业')
                trs += th(create_th_div("流水线成功率","(成功次数/执行总数)"))
                trs += th('质量评分')
                trs += th("代码扫描Bugs")
                trs += th("千行代码Bug数")
                trs += th("单元测试覆盖率")
                trs += th(create_th_div("冒烟用例执行成功率","(成功次数/执行总数)"))
                trs += th(create_th_div("场景用例执行情况成功率","(成功数量/用例总数)"))
                trs += th(create_th_div("基准性能测试执行成功率","(合规数量/用例总数)"))

                table1+=thead(trs)
                l=None

                for k,v in datas2.items():
                    if l is None:
                        l=tr()
                    else:
                        l += tr()
                    l += td(v['job_desc'])
                    l += td(v['job_name'])
                    rate = '{:.2f}%/({}/{})'.format(100 * float(v['whole_success']) / v['whole_run'], v['whole_success'],v['whole_run'])
                    l += td( rate)

                    if v.get('openapi_all',None) and v['openapi_all'] not in ('','NaN','NULL','尚未获取数据'):
                        openapi_test_rate = 100 * float(v['openapi_success']) / float(v['openapi_all']) if v['openapi_all'] != 0 else 0
                        openapi_result='{:.2f}%({}/{})'.format(openapi_test_rate,v['openapi_success'], v['openapi_all'])
                        openapi_result=a(openapi_result, href=v['openapi_report'], target="_blank")
                    else:
                        openapi_test_rate='NaN'
                        openapi_result='尚未获取数据'

                    if v.get('scene_total',None) not in ('NaN',None,'None',''):
                        scene_total = float(v['scene_total'])
                        scene_rate=100*float(v['scene_success']) / (scene_total if scene_total!=0 else 1)
                        scene_result='{:.2f}%({}/{})'.format(scene_rate, v['scene_success'], v['scene_total'])
                        if v['prod_name'].lower() not in ('monitor','alert','store-metric','databank','network'):
                            reports.update({v['prod_name'] :v['scene_suit']})
                    else:
                        scene_result='尚未获取数据'
                        scene_rate='None'

                    print(v['job_name'],v['sonar_bugs'], v['sonar_test_rate'], openapi_test_rate, scene_rate)
                    print(type(v['sonar_bugs']),type(v['sonar_test_rate']), type(openapi_test_rate), type(scene_rate))
                    score = add_score(v['sonar_bugs'], v['sonar_test_rate'], openapi_test_rate, scene_rate)
                    print('score',score)

                    l += td('{:.2f}'.format(score))
                    if v['sonar_bugs'] in ('NaN',None,'None',''):
                        l += td('尚未获取数据')
                    else:
                        l +=td(v.get('sonar_bugs','NaN'))

                    #千行代码bug数
                    print('v',v)
                    line, bugs, rate=get_sonar_file(v['job_name'].split('_')[0])
                    if line not in ('NaN',None,'None','') and bugs not in ('NaN',None,'None',''):
                        try:
                            l += td('{:.2f}'.format(1000*float(bugs)/float(line)))
                        except Exception as e:
                            print('千行代码bug率',e)
                    else:
                        l +=td('数据获取失败')
                    print('千行代码bug率', bugs,line)

                    if v['sonar_test_rate'] in ('NaN',None,'None',''):
                        l += td('NaN')
                    else:
                        l += td(a('{:.2f}%'.format(float(v['sonar_test_rate'])) , href=v['sonar_report'],target="_blank"))

                    if v['prod_name'] in no_api_list and openapi_result=='尚未获取数据':
                        l += td('无openapi数据')
                    else:
                        l += td(openapi_result)

                    if v.get('scene_total',None) not in ('NaN',None,'None',''):
                        l += td(a(scene_result,href='http://{}/scene_report/{}.html'.format(report_server,v['job_name'].split('_')[0]),target="_blank"))
                    elif v['prod_name'] in no_api_list:
                        l += td('无openapi数据')
                    else:
                        l+=td('尚未获取数据')

                    jmeter_result=v.get('jmx_result',None)
                    if jmeter_result not in ('NaN',None,'None',''):
                        jmeter_result=a(v['jmx_result'], href=v['jmx_report'],target="_blank")
                    else:
                        jmeter_result='尚未获取数据'
                    l += td(jmeter_result)
                table1 += tbody(l)
            tables.append(table1)

            print('zentao_data')
            zentao_data=get_zentao(days)

            ths='产品名称,bug总数,已关闭,已解决,未解决,重新打开'
            tags='build_name,bugs_total,bugs_closed,bugs_resolved,bugs_active,bugs_reactive'
            if zentao_data is not None:
                # caption('summary:')
                with table(cls='details',border="1",cellspacing="0", padding="0") as table2:
                    l = tr()
                    for i in ths.split(','):
                        l += th(i)
                    for i in zentao_data:
                        l = tr()
                        for j in tags.split(','):
                            l += td(i[j])
            else:
                table2="1"

            tables.append(table2)
            # print(tables)
            #基准测试
            # l += td(a(curLine[0], href="http://10.1.62.123:8003/index.html"))
            con_name={1:h2('最近{}天流水线执行效率统计'.format(days)),2:h2('最近{}天各产品的禅道bug数统计'.format(days))}
            content.add(h1('UYUN-开发流水线质量看板'))
            # input1 = input_(value="流水线统计", type="button", id="div1", index="3")
            # content.add(input1)
            # input1 = input_(value="禅道统计", type="button", id="div2", index="4")
            # content.add(input1)

            for i in range(1,3):
                content_i = div(con_name[i], cls="content-{}".format(i))
                content_i.add(tables[i - 1])
                # if i==1:
                #     content_i.add(h4('备注：基准性能合规要求:  平均响应时间在500毫秒内，最大响应时间不超过2秒'))
                # content.add(content_i)
                body.add(content_i)
            body.add(script(raw("""$("#pro_list").tablesorter({
    headers: {
        // 列序号默认从0开始
        //1: {
            //sorter: false
        //},
     }
} );"""),type='text/javascript'))
            body.add(script(raw(""" window.onload=function(){
            var aInput=document.getElementsByTagName('input');//获取到所有的input按钮,aInput是一个数组
            var aDiv=document.getElementsByTagName('div'); //获取到所有的div,aDiv是一个数组
            console.log(aDiv)
            for(var i=0;i<aInput.length;i++){               //按钮数组
                aInput[i].index=i;                          //i是按钮数组的下标,把i赋值给index,这样通过index就知道点击的是哪个按钮
                aInput[i].onclick=function(){
                    for(var j=0;j<aInput.length;j++){      //通过点击按钮的时候再次循环按钮，是为了清空active类
                        aInput[j].className=''             //清空active类

                    }
                    for(var i=0;i<aDiv.length;i++){        //把所有的divde的display重新设置为none，就是不显示
                        aDiv[i].style.display='none'
                    }
                    aInput[this.index].className='active'  //点击哪个按钮就哪个按钮加active类
                    aDiv[this.index].style.display='block' //点击哪个按钮就把第几个div给显示出来
                }
            }
        }"""), type='text/javascript'))
        print('文件生成路径',file_name+'.html')
        with open(file_name+'.html','w',encoding='utf-8') as f:
            f.write(main.render())
    except Exception as e:
        print('make html error:',e)
    return file_name.split('.html')[0],reports


def get_date(days):
    '''计算数据模块，被接口调用'''
    today = int(time.time())
    start_timestamp = float(today) - float(days) * 24 * 3600
    timeArray = time.localtime(start_timestamp)
    start_day = time.strftime("%Y-%m-%d %H:%M:%S", timeArray)
    # print(start_day)
    # print(start_timestamp)
    data = make_html(start_timestamp)
    file_content,suit_reports= txt2xml(data,days)
    for prod_name,ids in suit_reports.items():
        make_report(prod_name,ids)
    return file_content


def send_mail(receiver,file_name,days,data="",header="",report_name=""):
    '''发邮件模块，被接口调用'''
    password = "OtfyfRGjJon3Nk6"
    user = 'jenkins@broada.com'

    class EmailClass(object):
        global report_server
        def __init__(self, receiver,file_name,days=None,data='  <br>  流水线统计情况请见附件！  <br>',header="",report_name=""):
            self.curDateTime = str(time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()))  # 当前日期时间
            self.sender = 'jenkins@broada.com'  # 从配置文件获取，发件人
            self.receivers = receiver.split(',')  # 从配置文件获取，接收人
            # self.msg_title = '自动化构建部署失败' #从配置文件获取，邮件标题
            self.sender_server = 'mail.broada.com'  # 从配置文件获取，发送服务器
            self.From = '<jenkins@broada.com>'
            self.To = '{}'.format(receiver)
            self.status = False
            self.data=data
            self.file_name=file_name
            if days:
                self.header='最近{}天产品质量看板'.format(days)
                self.report_name='最近{}天产品质量看板.html'.format(days)
                #self.report_name = 'report_{}.html'.format(days)
            if header:
                self.header=header
                self.report_name=report_name

        '''
        配置邮件内容
        '''

        @property
        def setMailContent(self):
            msg = MIMEMultipart()
            msg['From'] = Header(self.From, 'utf-8')
            msg['To'] = self.To
            data = self.data
            message = MIMEText(data, 'html', 'utf-8')
            msg.attach(message)
            msg['Subject'] = Header(self.header, 'utf-8')
            html = self.addAttach(self.file_name.split('.html')[0]+'.html', filename=("gbk", "",self.report_name))
            msg.attach(html)
            return msg

        '''
        增加附件
        '''

        def addAttach(self, apath, filename='Report.html'):
            with open(apath, 'rb') as fp:
                attach = MIMEBase('application', 'octet-stream')
                attach.set_payload(fp.read())
                attach.add_header('Content-Disposition', 'attachment', filename=filename)
                encoders.encode_base64(attach)
                fp.close()
                return attach

        '''
        发送电子邮件
        '''

        def sendEmail(self, message):
            try:
                smtpObj = smtplib.SMTP()
                smtpObj.connect(self.sender_server, 25)
                smtpObj.login(user, password)
                smtpObj.sendmail(self.sender, self.receivers, message.as_string())
                smtpObj.quit()
                # print("邮件发送成功")
            except smtplib.SMTPException as ex:
                print("Error: 无法发送邮件.%s" % ex)

        # 发送调用
        @property
        def send(self):
            self.sendEmail(self.setMailContent)
    url='http://{}/reports/report_{}.html'.format(report_server,days)
    EmailClass(receiver, file_name,days,
               data='  <br>  流水线统计情况请查看附件，或者访问地址:  <br><a href="{0}">{0}</a>'.format(url),
               header=header,report_name=report_name).send

if __name__ == '__main__':
    res=get_date(days)
    print(res)
    send_mail(test_mail, res, 7)